import React, { FunctionComponent, useEffect } from "react";
import { useLocalStore, useObserver } from "mobx-react-lite";
import { reaction } from "mobx";
import classNames from "classnames";
import { pki } from "node-forge";
import { ErrorCode, getErrorMessage } from "../../core/errorcode";
import openapi, { Auth1ModifypasswordReq } from "@anyshare/openapi";
import Button from "antd/lib/button";
import Input from "antd/lib/input";
import { Password } from "../../controls";
import { useVerification } from "./verification-context";
import { VerificationType, IForgetPasswordState, IResetPasswordProps, IResetPasswordState } from "./type";
import { VerificationCodeColored, NewPasswordColored, ConfirmPasswordColored, BackOutlined } from "@anyshare/icons";

const PublicKey: any = pki.publicKeyFromPem(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JL0DcaMUHumSdhxXTxqiABBC
DERhRJIsAPB++zx1INgSEKPGbexDt1ojcNAc0fI+G/yTuQcgH1EW8posgUni0mcT
E6CnjkVbv8ILgCuhy+4eu+2lApDwQPD9Tr6J8k21Ruu2sWV5Z1VRuQFqGm/c5vaT
OQE5VFOIXPVTaa25mQIDAQAB
-----END PUBLIC KEY-----`);

export const ResetPassword: FunctionComponent<IResetPasswordProps> = ({ redirect, t }) => {
    const verification = useVerification() as IForgetPasswordState;
    const store = useLocalStore<IResetPasswordState>(() => {
        return {
            captcha: "",
            newPassword: "",
            confirmPassword: "",
            count: 60,
            errorStatus: ErrorCode.Normal,
            errorInfo: null,
            get getError(): string {
                switch (store.errorStatus) {
                    case ErrorCode.PasswordInvalidLocked:
                        return getErrorMessage(store.errorStatus, t, { time: store.errorInfo.detail.remainlockTime });
                    case ErrorCode.PasswordWeak:
                        return getErrorMessage(store.errorStatus, t, {
                            length: verification.strongPasswordLength.toString(),
                        });
                    default:
                        return getErrorMessage(store.errorStatus, t);
                }
            },
            checkInput(): boolean {
                switch (true) {
                    case !store.captcha:
                        store.errorStatus = ErrorCode.NoCaptcha;
                        return false;
                    case !store.newPassword:
                        store.errorStatus = ErrorCode.NoNewPassword;
                        return false;
                    case !store.confirmPassword:
                        store.errorStatus = ErrorCode.NoConfirmPassword;
                        return false;
                    case store.newPassword !== store.confirmPassword:
                        store.errorStatus = ErrorCode.NewConfirmInconsitent;
                        return false;
                    case store.newPassword === "123456":
                        store.errorStatus = ErrorCode.NewIsInitial;
                        return false;
                    default:
                        return true;
                }
            },
            checkSendVcodeStatus(): boolean {
                (async () => {
                    await verification.updatePasswordConfig();
                })();
                if (!verification.sendVcodeType.sendVcodeByEmail && !verification.sendVcodeType.sendVcodeBySMS) {
                    store.errorStatus = ErrorCode.CloseForgetPasswordResetBySend;
                    return false;
                } else if (
                    verification.verificationType === VerificationType.PHONE &&
                    !verification.sendVcodeType.sendVcodeBySMS
                ) {
                    store.errorStatus = ErrorCode.SMSClose;
                    return false;
                } else if (
                    verification.verificationType === VerificationType.EMAIL &&
                    !verification.sendVcodeType.sendVcodeByEmail
                ) {
                    store.errorStatus = ErrorCode.EmailClose;
                    return false;
                } else {
                    return true;
                }
            },
            async reset() {
                if (store.checkInput() && store.checkSendVcodeStatus()) {
                    try {
                        const body = {
                            account: "",
                            oldpwd: "",
                            newpwd: btoa(PublicKey.encrypt(store.newPassword, "RSAES-PKCS1-V1_5")),
                            isforgetpwd: true,
                            [verification.verificationType === VerificationType.PHONE
                                ? "telnumber"
                                : "emailaddress"]: verification.verificationValue,
                            vcodeinfo: {
                                uuid: verification.verificationId,
                                vcode: store.captcha,
                            },
                        };
                        await openapi.post("/eacp/v1/auth1/modifypassword", body as Auth1ModifypasswordReq);

                        // 重置成功，登录界面
                        window.location.href =
                            redirect || `${location.protocol}//${location.hostname}:${location.port}`;
                    } catch (e) {
                        if (e.response) {
                            const {
                                response: { data: err },
                            } = e;
                            store.errorInfo = err;
                            store.errorStatus = err.code;
                        } else {
                            store.errorInfo = null;
                            store.errorStatus = ErrorCode.NoNetwork;
                        }
                    }
                }
            },
            async sendVcodeAgain() {
                if (store.checkSendVcodeStatus()) {
                    try {
                        if (verification.verificationType === VerificationType.PHONE) {
                            // 短信验证
                            const { data } = await openapi.post(("/eacp/v1/auth1/sendvcode" as unknown) as any, {
                                telnumber: verification.verificationValue,
                                uuid: verification.verificationId,
                            });
                            verification.updateVerificationId(((data as unknown) as any).uuid);
                            store.count = 60;
                        } else if (verification.verificationType === VerificationType.EMAIL) {
                            // 邮箱验证
                            const { data } = await openapi.post(("/eacp/v1/auth1/sendvcode" as unknown) as any, {
                                emailaddress: verification.verificationValue,
                                uuid: verification.verificationId,
                            });
                            verification.updateVerificationId(((data as unknown) as any).uuid);
                            store.count = 60;
                        }
                    } catch (e) {
                        if (e.response) {
                            const {
                                response: { data: err },
                            } = e;
                            store.errorInfo = err;
                            switch (err.code) {
                                case ErrorCode.PasswordChangeNotSupported:
                                    store.errorStatus =
                                        verification.verificationType === VerificationType.PHONE
                                            ? ErrorCode.SMSUserNoLocal
                                            : ErrorCode.EmailUserNoLocal;
                                    break;
                                case ErrorCode.PasswordRestricted:
                                    store.errorStatus =
                                        verification.verificationType === VerificationType.PHONE
                                            ? ErrorCode.SMSUserControlled
                                            : ErrorCode.EmailUserControlled;
                                    break;
                                case ErrorCode.SendVcodeServerUnavailable:
                                    store.errorStatus =
                                        verification.verificationType === VerificationType.PHONE
                                            ? ErrorCode.SMSClose
                                            : ErrorCode.EmailClose;
                                    break;
                                default:
                                    store.errorStatus = err.code;
                            }
                        } else {
                            store.errorInfo = null;
                            store.errorStatus = ErrorCode.NoNetwork;
                        }
                    }
                }
            },
        };
    });

    useEffect(
        () =>
            reaction(
                () => [store.count],
                () => {
                    if (store.count > 0) {
                        const timer = setTimeout(() => {
                            store.count = store.count - 1;
                        }, 1000);

                        return () => {
                            clearTimeout(timer);
                        };
                    }
                },
                { fireImmediately: true }
            ),
        []
    );

    return useObserver(() => {
        return (
            <div className="content">
                <BackOutlined
                    className="back back-pass"
                    onClick={async () => {
                        await verification.updatePasswordConfig();
                        verification.returnSendVcode();
                    }}
                />
                <div className="reset-password-tip">
                    <div className="verification-message">
                        {verification.verificationType === VerificationType.PHONE
                            ? t("sms-captcha-tip")
                            : t("email-captcha-tip")}
                        {verification.verificationType === VerificationType.PHONE
                            ? verification.verificationValue.replace(/(\d{3})(\d{5})(\d{3})/g, "$1*****$3")
                            : verification.verificationValue.replace(/(.{3}).+(.{2}@.+)/g, "$1*****$2")}
                    </div>
                </div>
                <div className="vcode-wrapper">
                    <Input
                        className="input-item reset-password-item reset-password-captcha-item"
                        type="text"
                        autoComplete="off"
                        prefix={<VerificationCodeColored className="icon" />}
                        placeholder={t("captcha")}
                        value={store.captcha}
                        onChange={(e) => {
                            store.captcha = e.target.value;
                            store.errorStatus = ErrorCode.Normal;
                        }}
                        onDrop={(e) => {
                            e.preventDefault();
                        }}
                    />
                    <div
                        className={classNames("vcode vcode-captcha", store.count > 0 && "vcode-disabled vcode-captcha")}
                        onClick={() => {
                            if (store.count > 0) {
                                return false;
                            } else {
                                store.sendVcodeAgain();
                            }
                        }}
                    >
                        {store.count > 0 ? t("send-captcha-again", { count: store.count }) : t("send-captcha")}
                    </div>
                </div>
                <Password
                    className="input-item reset-password-item"
                    type="password"
                    autoComplete="new-password"
                    prefix={<NewPasswordColored className="icon" />}
                    placeholder={t("new-password")}
                    value={store.newPassword}
                    onChange={(e) => {
                        store.newPassword = e.target.value;
                        store.errorStatus = ErrorCode.Normal;
                    }}
                    onDrop={(e) => {
                        e.preventDefault();
                    }}
                />
                <Password
                    className="input-item reset-password-item"
                    type="password"
                    autoComplete="new-password"
                    prefix={<ConfirmPasswordColored className="icon" />}
                    placeholder={t("confirm-password")}
                    value={store.confirmPassword}
                    onChange={(e) => {
                        store.confirmPassword = e.target.value;
                        store.errorStatus = ErrorCode.Normal;
                    }}
                    onDrop={(e) => {
                        e.preventDefault();
                    }}
                />
                <Button
                    className="oem-button reset-password-button as-components-oem-background-color"
                    type="primary"
                    onClick={store.reset}
                >
                    {t("reset-password")}
                </Button>
                {store.errorStatus !== ErrorCode.Normal ? (
                    <div className="error-message-text">{store.getError}</div>
                ) : null}
            </div>
        );
    });
};
